﻿using Sustainalytics.Utils;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Sustainalytics.EmailHelper
{
    public class EmailHelper : IEmailHelper
    {
        string smtpServer = "";
        int smtpPort = 0;
        string smtpUsername = "";
        string smtpPassword = "";
        bool sendEmailToQa = false;
        string qaEmail = "";

        private EmailHelper() { }

        public static IEmailHelper GetInstance()
        {
            var emailHelper = new EmailHelper();
            emailHelper.smtpServer = ConfigurationManager.AppSettings["smtpServer"];
            emailHelper.smtpPort = int.Parse(ConfigurationManager.AppSettings["smtpPort"]);
            emailHelper.smtpUsername = ConfigurationManager.AppSettings["smtpUsername"];
            emailHelper.smtpPassword = ConfigurationManager.AppSettings["smtpPassword"];
            emailHelper.sendEmailToQa = bool.Parse(ConfigurationManager.AppSettings["SendEmailToQA"]);
            emailHelper.qaEmail = ConfigurationManager.AppSettings["QAEmail"];
            return emailHelper;
        }

        public async Task SendEmail(IEnumerable<string> toAddresses, IEnumerable<string> ccAddresses, string subject, string body)
        {
            if (UnitTestDetector.IsInUnitTest)
                return;

            Regex emailValidator = new Regex(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*");

            if (!emailValidator.IsMatch(smtpUsername))
                throw new ArgumentException(string.Format("Invalid email address \"{0}\" for sender!", smtpUsername));

            using (MailMessage message = new MailMessage())
            {
                message.Subject = subject;
                message.Body = body;
                message.IsBodyHtml = true;
                message.From = new MailAddress(smtpUsername);

                if (sendEmailToQa)
                    message.To.Add(qaEmail);
                else
                {
                    if (toAddresses != null)
                    {
                        foreach (var toAddress in toAddresses.Where(a => !string.IsNullOrWhiteSpace(a)))
                        {
                            if (!emailValidator.IsMatch(toAddress))
                            {
                                throw new ArgumentException(string.Format("Invalid email address \"{0}\" for <to> recipient!", toAddress));
                            }

                            message.To.Add(toAddress);
                        }
                    }
                }

                if (ccAddresses != null)
                {
                    foreach (var ccAddress in ccAddresses.Where(a => !string.IsNullOrWhiteSpace(a)))
                    {
                        if (!emailValidator.IsMatch(ccAddress))
                        {
                            throw new ArgumentException(string.Format("Invalid email address \"{0}\" for <cc> recipient!", ccAddress));
                        }

                        message.CC.Add(ccAddress);
                    }
                }

                if (message.To.Count == 0 && message.CC.Count == 0)
                {
                    throw new ArgumentException("No valid email recipient specified!");
                }

                using (SmtpClient mailClient = new SmtpClient(smtpServer, smtpPort))
                {
                    mailClient.Credentials = new NetworkCredential(smtpUsername, smtpPassword);
                    mailClient.EnableSsl = true;
                    await mailClient.SendMailAsync(message);
                }
            }
        }
    }
}
